1   /************************************************************
2   *                     Copyright                            *
3   * Portions of this software are Copyright (c) 1993 - 2002, *
4   * Chad Z. Hower (Kudzu) and the Indy Pit Crew              *
5   *  - http://www.nevrona.com/Indy/                          *
6   ************************************************************/
7   package org.indy.util;
8   
9   import java.io.ByteArrayInputStream;
10  import java.io.ByteArrayOutputStream;
11  import java.io.IOException;
12  
13  
14  /***
15   *  A light weight read-write buffer used by Indy.
16   *
17   * NOTE: This class is not thread-safe; if you wish to use
18   * this IdBuffer in a multi-threaded environment you must
19   * provide your own synchronization.
20   *
21   *@author    OTG
22   *@version   1.0
23   */
24  public class IndyBuffer extends ByteArrayOutputStream {
25    private OpenByteArrayInputStream reader = new OpenByteArrayInputStream(buf, 0, 
26                                                                           buf.length);
27  
28    /***
29     *  Checks whether reader's buffer is in sync with writer's,
30     *  and refreshes if neccessary.
31     */
32    protected void readerIsDirty() {
33      //could be that the whole buffer reference has changed,
34      //or just that the count needs updating
35      if (reader.getBufLength() != buf.length) {
36        //something of a hack
37        reader = new OpenByteArrayInputStream(buf, reader.getPos(), 
38                                              count - reader.getPos());
39      }
40      else if (count != reader.getCount()) {
41        reader.setCount(count);
42      }
43    }
44  
45    /***
46     *  Clears the buffer
47     */
48    public void clear() {
49      reset();
50      reader.reset();
51    }
52  
53    /***
54     *  Returns some data from the buffer non-destructively
55     *  (i.e. doesn't remove it).
56     *
57     *@param  b    An array of bytes to read into
58     *@param  off  The offset to start filling <code>b</code> at
59     *@param  len  The number of bytes to read
60     *@throws IndexOutOfBoundsException If off or len are invalid
61     *@see    #read(byte[],int,int)
62     */
63    public void peek(byte[] b, int off, int len) {
64      if ((off < 0) || (off > count) || (len < 0) || ((off + len) > count) || 
65            ((off + len) < 0)) {
66        throw new IndexOutOfBoundsException();
67      }
68  
69      System.arraycopy(buf, off, b, 0, len);
70    }
71  
72    /***
73     *  Reads some bytes from the buffer.
74     *
75     *@param  b    An array of bytes to read into.
76     *@param  off  The offset to start filling <code>b</code> at
77     *@param  len  The number of bytes to read
78     *@see    #peek(byte[],int,int)
79     */
80    public void read(byte[] b, int off, int len) {
81      readerIsDirty();
82  
83  
84      /*** @todo Bounds checking here */
85      reader.read(b, off, len);
86    }
87  
88    /***
89     *  Attempts to read a line of text from the buffer. See
90     *  the general contract of {@Link OpenByteArryInputStream#readLine()}.
91     *
92     *@return               A line of text from the buffer, or null if no line is found.
93     *@throws  IOException  If an IO error occurrs.
94     */
95    public String readLine() throws IOException {
96      readerIsDirty();
97  
98      return reader.readLine();
99    }
100 
101   /***
102    *  Returns the current number of bytes in the buffer.
103    *
104    *  @return    The current size of the buffer in bytes.
105    */
106   public int size() {
107     readerIsDirty();
108 
109     return count - reader.getPos();
110   }
111 
112   /***
113    *  A ByteArrayInputStream that exposes it's current
114    *  position so it can be synced with the overall buffer.
115    *
116    *@author    OTG
117    */
118   private class OpenByteArrayInputStream extends ByteArrayInputStream {
119     /***
120      *  Constructs a new instance.
121      *
122      *@param  b       The buffer to use.
123      *@param  offset  The offset at which to start reads.
124      *@param  len     The length of the buffer.
125      */
126     public OpenByteArrayInputStream(byte[] b, int offset, int len) {
127       super(b, offset, len);
128     }
129 
130     private void setCount(int newCount) {
131       super.count = newCount;
132     }
133 
134     /***
135      *  Gets the current read position
136      *
137      *@return    The read position of the buffer.
138      */
139     public int getPos() {
140       return this.pos;
141     }
142 
143     /***
144      *  Gets the current length of the buffer array.
145      *
146      *@return    The length of the buffer array.
147      */
148     public int getBufLength() {
149       return super.buf.length;
150 
151       //make *positive* we're getting the right one!
152     }
153 
154     /***
155      *  Gets the current amount of buffered data.
156      *
157      *@return    The amount of buffered data in bytes.
158      */
159     public int getCount() {
160       return super.count;
161     }
162 
163     byte[] peek() {
164       byte[] res = new byte[this.count];
165 
166       System.arraycopy(super.buf, 0, res, 0, this.count);
167 
168       return res;
169     }
170 
171     /***
172      *  Reads a line of character data from the buffer.
173      *  This, unlike java.io.BufferedReader will return
174      *  null if there is data, but no EOL.
175      *
176      *  It allows any combination of LF and CR.
177      *
178      *@return               A line of text, or NULL if no EOL is present.
179      *@throws  IOException  If an IO error occurs.
180      */
181     public String readLine() throws IOException {
182       byte[] b = new byte[count - pos];
183 
184       System.arraycopy(buf, pos, b, 0, count - pos);
185 
186       String s = new String(b);
187       char[] c = s.toCharArray();
188 
189       boolean pairedBreak = false;
190       int cpos = 0;
191 
192       for (int i = 0; i < c.length; i++) {
193         if ((c[i] == '\n') || (c[i] == '\r')) {
194           cpos = i;
195 
196           if ((i + 1) < c.length) {
197             if ((c[i + 1] == '\n') || (c[i + 1] == '\r')) {
198               pairedBreak = true;
199             }
200           }
201 
202           break;
203         }
204       }
205 
206       String res = null;
207 
208       if (cpos > 0) {
209         pos += (s.substring(0, cpos).getBytes().length + 1);
210         res = s.substring(0, cpos);
211       }
212 
213       //get rid of the feed chars
214       if (pairedBreak) {
215         pos++;
216       }
217 
218       return res;
219     }
220   }
221 }
This page was automatically generated by Maven